package com.stropheware.droidDefense;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import com.stropheware.pathfinding.Node;
import com.stropheware.pathfinding.Path;
import com.stropheware.pathfinding.PathFinder;
import com.stropheware.pathfinding.Path.Step;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.util.Log;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;

public abstract class AbstractEnemy {
	
	protected static final int ENEMY_BUFFER_MS = 2 * 1000;
	protected static final String TAG = "AbstractEnemy";
	protected int health;
	protected int maxHealth;
	protected Context context;
	protected GameBoard gameBoard;
	protected Drawable drawable;
	protected boolean visible = false;
	protected AnimationDrawable animationDrawable;
	protected int xpx;
	protected int ypx;
	protected int nextXpx;
	protected int nextYpx;
	protected double cellSpeed;
	protected double speed;
	protected int reward;
	protected Timer bufferTimer = new Timer();
	protected Node currentNode = null;
	private ArrayList<Step> currentPathSteps = null;
	protected ArrayList<Step> tempPathSteps = null;
	protected int currentStep = 0;
	public int addToEnemyPx; //to get to center of enemy
	public int widthPixels;
	
	private GameManager gameManager;
	private EnemyManager enemyManager;
	
	/**size of enemy in terms of cells, if size == 2 then size is 2x2 cells*/
	public static int SIZE = 3;	
	
	/**Tower Pop Up Variables*/
	public static float popUpLeft;
	public static float popUpTop;
	public static float popUpRight;
	public static float popUpBottom;
	public static Paint popUpPaint = new Paint();
	public static Paint popUpHealthPaint = new Paint();
	public static Paint popUpOutlinePaint = new Paint();
	public static RectF popUp = new RectF();
	public static final int popUpWidth = 130;
	public static final int popUpHeight = 80;
	public boolean displayPopUp;
	int i;
	public Cell currentLocation;
		
	public AbstractEnemy(Context context, GameBoard gameBoard, EnemyManager enemyManager) {
		this.context = context;
		this.gameBoard = gameBoard;
		this.enemyManager = enemyManager;
		this.gameManager = enemyManager.gameManager;
		ypx = 0;
		xpx = 0;
		currentNode = gameBoard.startNode;
		addToEnemyPx = (SIZE / 2)  * gameBoard.cellSideLength;
		
		displayPopUp = false;
		popUpPaint.setColor(Color.TRANSPARENT);
		popUpPaint.setAntiAlias(true);	
		popUpHealthPaint.setColor(Color.RED);
		popUpHealthPaint.setAntiAlias(true);	
		popUpOutlinePaint.setAntiAlias(true);
		popUpOutlinePaint.setColor(Color.RED);
		popUpOutlinePaint.setStyle(Paint.Style.STROKE);
		popUpOutlinePaint.setStrokeWidth(2);
		i = 0 ;
		widthPixels = gameBoard.cellSideLength * SIZE;
	}
	
	public AbstractEnemy(){}
	
	public void updatePath(ArrayList<Step> newPath) {
		if(!visible)currentPathSteps = newPath;
		else {
			Node currentNode = PathFinder.getNearestNode(xpx,ypx);
			//rerun a* for each enemy on path probably too slow!
			Path updatedPath = gameManager.gameThread.pathFinder.findPath(currentNode, gameBoard.targetNode, gameBoard);
			tempPathSteps = updatedPath.steps;
			currentStep = 0;
		}
	}
	
	public void hit(int damage) {
		health -= damage;
		if (health <= 0) {
			visible = false;
			Log.d(TAG, "enemy dead");
			enemyManager.enemyKilled(this);
		}
	}
	
	public void startAttacking() {
		currentStep = 0;
		findNextStepPixels();
		visible = true;
	}
	
	public void drawDrawable(Canvas canvas) {
		if(visible) {
			drawable.setBounds(xpx, ypx, xpx + gameBoard.cellSideLength * SIZE, ypx + gameBoard.cellSideLength * SIZE);
			drawable.draw(canvas);
		}
	}
	
	/*
	 * speed now defined as # of ticks to move across one cell
	 */
	public void update(int tickCount) {
		if(visible) {
			if(tickCount % speed == 0) {
				updateCurrentLocation();	
			}
		}
	}
	
	private void updateCurrentLocation() {
		if(xpx == nextXpx && ypx == nextYpx) {
			currentStep++;
			Log.d(TAG, "going to next step" + this);
			if(currentStep >= currentPathSteps.size() - 1) {
				visible = false;
				enemyManager.enemyCompletedGoal();
				return;
			}
			findNextStepPixels();
		}
		if(nextXpx > xpx) xpx+=1;
		else if(nextXpx < xpx) xpx-=1;
		if(nextYpx > ypx) ypx+=1;
		else if(nextYpx < ypx) ypx-=1;
	}
	
	protected void findNextStepPixels() {
		if(currentStep + 1 < currentPathSteps.size()) {
			Step temp = currentPathSteps.get(currentStep + 1);
			nextXpx = PathFinder.nodes[temp.x][temp.y].occupiedCells[0].pxColumn;
			nextYpx = PathFinder.nodes[temp.x][temp.y].occupiedCells[0].pxRow;
		}
	}
	
	public int getProjectileX() {
		return xpx + ((SIZE / 2) * gameBoard.cellSideLength);
	}
	
	public int getProjectileY() {
		return ypx + ((SIZE / 2) * gameBoard.cellSideLength);
	}
	
	public void reset(int delay) {
		xpx = gameBoard.startCell.pxColumn;
		ypx = gameBoard.startCell.pxRow;
		health = maxHealth;
		if(delay == 0) startAttacking();
		else {
			bufferTimer.schedule(new EnemyBufferTask(), delay * ENEMY_BUFFER_MS);
		}
	}
	
	class EnemyBufferTask extends TimerTask {
		public void run() {
			Log.d(TAG, "ATTACK!");
			startAttacking();
		}
	}
	
	public void showPopUp() {
		if(xpx+AbstractEnemy.popUpWidth >= gameBoard.actualWidth)AbstractEnemy.popUpLeft = gameBoard.actualWidth-popUpWidth-10;
		else AbstractEnemy.popUpLeft = xpx;
		if(ypx+widthPixels+popUpHeight >= gameBoard.actualHeight)AbstractEnemy.popUpTop = xpx-popUpHeight;
		else AbstractEnemy.popUpTop = ypx+widthPixels;
		AbstractEnemy.popUpRight = AbstractEnemy.popUpLeft+popUpWidth;
		AbstractEnemy.popUpBottom = AbstractEnemy.popUpTop+popUpHeight;
	}
	
	public void drawPopUp(Canvas canvas){
		if(displayPopUp && visible){
		popUpPaint.setShadowLayer(4, 0, 1, 0xbb000000);
		popUp.set(popUpLeft,popUpTop,popUpRight,popUpBottom);
		drawable.setBounds((int)popUpLeft+5, (int)popUpTop+30, (int)popUpLeft+45, (int)popUpTop+70);
		canvas.drawRoundRect(popUp, 7, 7, popUpPaint);
		
		popUp.set(popUpLeft+3,popUpTop+3,popUpRight-3,popUpBottom-3);
		canvas.drawRoundRect(popUp, 3, 3, popUpOutlinePaint);
		TextPaint t = new TextPaint();
		t.setAntiAlias(true);
		t.setTextSize(11);

		t.setColor(Color.WHITE);
		canvas.drawText("Name: ", popUpLeft+50, popUpTop+40, t);
		t.setColor(Color.MAGENTA);
		canvas.drawText("f4rquad", popUpLeft+85, popUpTop+40, t);
		t.setColor(Color.WHITE);
		canvas.drawText("Speed: ", popUpLeft+50, popUpTop+55, t);
		t.setColor(Color.GREEN);
		canvas.drawText("10", popUpLeft+85, popUpTop+55, t);
		t.setColor(Color.WHITE);
		canvas.drawText("Reward: ", popUpLeft+50, popUpTop+70, t);
		t.setColor(Color.YELLOW);
		canvas.drawText(""+reward+"g", popUpLeft+90, popUpTop+70, t);
		t.setColor(Color.WHITE);
		//canvas.drawText("Sell for: ", popUpLeft+55, popUpTop+75, t);
		//t.setColor(Color.YELLOW);
		//canvas.drawText("100g", popUpLeft+96, popUpTop+75, t);
		t.setTextSize(9);
		popUp.set(popUpLeft+20,popUpTop+8,popUpLeft+popUpWidth-20,popUpTop+21);
		canvas.drawRoundRect(popUp, 2, 2, popUpHealthPaint);
		canvas.drawText(""+this.health+"/"+this.maxHealth, popUpLeft+54, popUpTop+18, t);
		drawable.draw(canvas);

		}
		}
}
